<script type="text/javascript">
	function pasarVariables(pagina, nombres) {
  pagina +="?";
  nomVec = nombres.split(",");
  for (i=0; i<nomVec.length; i++)
    pagina += nomVec[i] + "=" + escape(eval(nomVec[i]))+"&";
  pagina = pagina.substring(0,pagina.length-1);
  location.href=pagina;
}
</script>
	<h2>Cap&iacute;tulo 8 Informacion de UNDO</h2>
<br /><br />
<p class="definicion" align="justify">
 &nbsp;&nbsp;Nos podemos encontrar en la situacion que despues de ejecutar una sentencia DML, nos damos cuenta que nos hemos equivocado. Para poder desacer estos cambios es necesario que oracle almacene la informacion necesaria para volver a hacia atras estos cambios. A esta informaci&oacute;n se llama datos de UNDO. Otro beneficio de los datos de undo es lo que llamamos consistencia de lectura. Es decir, imaginemos que dos usuarios se encuentrar accediendo a la misma tabla, uno de ellos lanza un SELECT mientras que el otro lanza un UPDATE. Para mantener la consistencia de lectura, a este usuario se le tienen que presentar los datos segun establa la tabla justo despues de lanzar el SELECT y antes de que se ejecute el UPDATE. Sera sobre los datos de UNDO sobre lo que tratar&aacute; este c&aacute;pitulo, ademas de los diferentes bloqueos de acceso que puede tener una tabla dentro de Oracle.
<br /><br />
Como hemos dicho la informacion de undo nos puede aportar varios beneficios:
</p>
<blockquote>
- Permite hacer un roll back de los datos que se han cambiado en la base de datos.<br />
- Permite mantener la consistencia en la lectura.<br />
- Permite ejecutar sentencias de FlashBack.<br />
- En algunos modos de recuperacion de la base de datos.<br />
</blockquote>
<br />
<h3><b>SEGMENTOS DE UNDO</b></h3>
<p class="definicion" align="justify">
 &nbsp;&nbsp;Los segmentos de UNDO al igual que otros tipo de segmentos de la base de datos se componen a su vez de extensiones y bloques. Pero estos segmentos se almacenan en tablespace de undo, aunque una base de datos puede tener varios tablespace de undo, &uacute;nicamente uno de ellos puede estar activo. Un segmento de undo puede tener informacion de undo de varias tablas involucradas en una transaccion. El segmento de undo ira creciendo dentro de un buffer circular, es decir, nueva informacion de undo puede ir sobreescrita antigua informacion de undo. Esto en el caso, que la informacion sobreescrita sea necesaria para desacer una transaccion, Oracle devolvera un error.
<br /><br />
Como hemos comentado anteriormente al trabajar con la iformacion de UNDO podemos obtener varios errores:
</p>
<blockquote>
- ORA-01650: Unable to extend rollback segment: En el caso de que nos quedemos sin espacio en el tablespace de UNDO.<br />
- ORA-01555: Snapshot too old: En queries que llevan mucho tiempo y el proceso de escritura circular borra datos necesarios para esa query.<br />
</blockquote>
<p class="definicion" align="justify">
Vamos a presentar algunos parametros de inicializacion que podemos configurar para minimizar la aparicion de estos errores. Tambien vamos a ense&ntilde;ar como consultar la tabla V$UNDOSTAT para calcular el tama&ntilde;o optimo de nuestro tablespace de UNDO. Por &uacute;ltimo, explicaremos como evitar que aparezca el error ORA-01555 en queries muy largas utilizando la opcion RETENTION GUARANTEE.
<br /><br />
Los parametros de inicializacion que hemos comentado son:
</p>
<blockquote>
- UNDO_MANAGEMENT=[AUTO|MANUAL]: Configura la forma en la que se va a tratar la informacion de UNDO dentro de la base de datos. De forma manual utilizando segmentos de rollback o de forma automatica  utilizando un unico tablespace para la informacion de UNDO. Al modificar este parametro sera necesario reiniciar la instancia.
</blockquote>
<blockquote style="COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif"><pre><p>
sql > alter system  set undo_management = manual scope=spfile;
</p></pre></blockquote>
<blockquote>
- UNDO_TABLESPACE: En este parametro configuramos el nombre del tablespace de undo que vamos a utilizar para garantizar la consistencia de lectura.
<br />
- UNDO_RETENTION: Especifica el numero de segundos que la informacion de UNDO de la que ya se ha hecho un commit debe de permanecer en los segmentos de UNDO antes de ser sobreescrita. Se puede dar que aun no se hayan alcanzado estos segundos, pero se necesite mas espacio de UNDO, por lo que esta informacion sera sobreescrita.
</blockquote>
<p class="definicion" align="justify">
Vamos a ver la utilidad de la tabla V$UNDOSTAT para calcular el tama&ntilde;o optimo de nuestro tablespace de UNDO:
</p>
<blockquote style="COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif"><pre><p>
SQL> select
 to_char(begin_time,'yyyy-mm-dd hh24:mi:ss') starttime,
 to_char(end_time,'yyyy-mm-dd hh24:mi:ss') endtime,
 undoblks,
 maxquerylen maxqrylen
 from v$undostat;

SALIDA:

STARTTIME ENDTIME UNDOBLKS MAXQRYLEN
------------------- ------------------- -------- ---------
2004-08-01 08:46:11 2004-08-01 08:48:47 13 0
2004-08-01 08:36:11 2004-08-01 08:46:11 61 0
2004-08-01 08:26:11 2004-08-01 08:36:11 31 0
. . .
2004-07-30 09:36:11 2004-07-30 09:46:11 68 0
2004-07-30 09:26:11 2004-07-30 09:36:11 30 0
2004-07-30 09:16:11 2004-07-30 09:26:11 52 0
2004-07-30 09:06:11 2004-07-30 09:16:11 626 190
2004-07-30 08:56:11 2004-07-30 09:06:11 203 0
2004-07-30 08:46:11 2004-07-30 08:56:11 66 0
2004-07-30 08:36:11 2004-07-30 08:46:11 31 0
2004-07-30 08:26:11 2004-07-30 08:36:11 73 0
</p></pre></blockquote>
<p class="definicion" align="justify">
 &nbsp;&nbsp;Como vemos a las 9:06 se ejecuto una query que requirio de gran cantidad de espacio en el tablespace de UNDO. Ejecutar queries de gran necesidad de procesado van a requerir que la informacion de undo se encuentre presente durante bastante tiempo. Por lo que pueden ocurrir errores ORA-01555 Snapshot too old.
<br /><br />
Para dimensionar correctamente el tablespace de UNDO tendremos que tener en cuenta la siguiente formula
<br /><br />
<b><i>undo_tablespace_size= Undo Retention * UPS (Numero maximo de bloques utilizados por segundo)</i></b>
<br /><br />
Con un periodo de retencion de 12 horas (43200), un tama&ntilde;o de bloque de 8K y con el un numero maximo de bloques por segundo, query anterior) tenemos que el tama&ntilde;o de nuestro tablespace seria:
<br /><br />
<b><i>undo_tablespace_size = 43200 * 626 * 8192 = 221537894400 = 206GB</i></b>
<br /><br />
Se recomienda un tama&ntilde;o de entre  el 10% o el 20% de este valor.
</p>
<br />
<h3><b>RETENTION GUARANTEE</b></h3>
<p class="definicion" align="justify">
Este parametro va a asegurar que la informacion de undo de transacciones que ya han realizado un COMMIT permanezca el tiempo configurado en UNDO_RETENTION.
<br /><br />
Activacion
</p>
<blockquote style="COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif"><pre><p>
sql > alter tablespace undotbs1 retention guarantee;
</p></pre></blockquote>
<p class="definicion" align="justify">
Desactivacion
</p>
<blockquote style="COLOR: #2e5348; FONT-SIZE: 12px; FONT-WEIGHT: bold FONT:Arial, Helvetica, sans-serif"><pre><p>
sql > alter tablespace undotbs1 retention noguarantee;
</p></pre></blockquote>
</div>